package com.jsn.android.audio2


import android.annotation.SuppressLint
import android.content.ContentResolver
import android.content.ContentUris
import android.database.Cursor

import android.net.Uri
import android.provider.MediaStore
import android.service.media.MediaBrowserService
import android.view.View
import android.widget.Button
import android.widget.ProgressBar
import androidx.databinding.BindingAdapter
import androidx.lifecycle.*
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.jsn.android.audio2.databinding.ActivityAudioTrackBinding
import com.jsn.baselibx.ui.BaseActivity
import com.jsn.baselibx.utils.Logs
import kotlinx.android.synthetic.main.activity_audio_track.*
import kotlinx.coroutines.*
import java.lang.Exception
import java.util.concurrent.TimeUnit

fun View.visible(visible:Boolean){
    visibility=if(visible) View.VISIBLE else View.GONE
}

class AudioTrackActivity :BaseActivity<ActivityAudioTrackBinding>() {
    lateinit var adapter: AudioAdapter

    lateinit var viewModel: ViewModel

    data class Audio(val uri: Uri,
                     val name: String,
                     val duration: Int,
                     val size: Int){
        override fun toString(): String {
            return "uri:${uri.toString()},name:${name},duration:${duration.toString()},size:${size.toString()}"
        }
    }


    @SuppressLint("InlinedApi")
    val projection = arrayOf(
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.DISPLAY_NAME,
        MediaStore.Audio.Media.DURATION,
        MediaStore.Audio.Media.SIZE
    )

    // Show only videos that are at least 5 minutes in duration.
    @SuppressLint("InlinedApi")
    val selection = "${MediaStore.Audio.Media.DURATION} >= ?"
    val selectionArgs = arrayOf(
        TimeUnit.MILLISECONDS.convert(0, TimeUnit.MINUTES).toString()
    )

    // Display videos in alphabetical order based on their display name.
    val sortOrder = "${MediaStore.Audio.Media.DISPLAY_NAME} ASC"

    //val queryComplete=MutableLiveData<Boolean>().apply {value=false }

    val videoReault=MutableLiveData<Result<List<Audio>>>()

    override fun getContentView(): Int {
        return R.layout.activity_audio_track
    }

    override fun initUI() {
        viewModel= ViewModelProviders.of(this,AudioFactory(videoReault)).get(ViewModel::class.java)
        initRV()
        bt.setOnClickListener { start() }
        mBinding.viewModle=viewModel
        mBinding.lifecycleOwner=this


        viewModel.videoResult.observe(this){result ->
            pb.visible(result is Result.Loading)
            bt.isEnabled=!(result is Result.Loading)
            adapter.submitList(result.successOr(emptyList()))
            tv.text=result.toString()
            Logs.e("observeaudionums"+result.successOr(emptyList()).size.toString())
        }
    }

    private fun initRV() {
        rv.layoutManager=LinearLayoutManager(this)
        rv.adapter=AudioAdapter().also { adapter=it }

    }


    @SuppressLint("Recycle")
    override fun initData() {
      start()
    }

    fun start(){
        videoReault.value=Result.Loading
        scope.launch {
            delay(500)//delay
            try {
                val query=contentResolver.query(
                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                    projection,
                    selection,
                    selectionArgs,
                    sortOrder
                )
                //queryComplete.postValue(true)
                query?.use {cursor->
                    val audios = mutableListOf<Audio>()
                    var nums=0
                    while (cursor.moveToNext()){
                        Logs.e("nums:${++nums}")
                        val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)
                        val nameColumn =
                            cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)
                        val durationColumn =
                            cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)
                        val sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)
                        val id = cursor.getLong(idColumn)
                        val name = cursor.getString(nameColumn)
                        val duration = cursor.getInt(durationColumn)
                        val size = cursor.getInt(sizeColumn)

                        val contentUri: Uri = ContentUris.withAppendedId(
                            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                            id
                        )
                        audios += Audio(contentUri,name,duration,size)
                    }
                    Logs.e("audionums"+audios.size.toString())
                    videoReault.postValue(Result.Success(audios))
                }
            }catch (e:Exception){
                videoReault.postValue(Result.Error(e))
            }finally {

            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        job.cancel()
    }

    val job= SupervisorJob()
    val scope= CoroutineScope(Dispatchers.IO+job)

}



class ViewModel( val videoResult:MutableLiveData<Result<List<AudioTrackActivity.Audio>>>):androidx.lifecycle.ViewModel(){

}

@Suppress("UNCHECKED_CAST")
class AudioFactory(val videoResult:MutableLiveData<Result<List<AudioTrackActivity.Audio>>>):ViewModelProvider.Factory{
    override fun <T : androidx.lifecycle.ViewModel?> create(modelClass: Class<T>): T {
      return ViewModel(videoResult) as T
    }
}

//prevent from double click
inline fun View.setSafeListener( crossinline performClick:(View)->Unit){
    var lastClick:Long=0 //kotlin闭包

    setOnClickListener{
        val currentTimeMillis = System.currentTimeMillis()
        val interval = currentTimeMillis - lastClick
        lastClick=currentTimeMillis

        if(interval<500L) return@setOnClickListener //using a tag when return from lambda
        performClick(it)
    }
}
